/* eslint-disable */
<template>
  <div
    id="message-send-box-wrapper"
    @drop="dropHandler"
  >
    <div class="send-header-bar">
      <div class="send-img flex-center" @click="handleSendImageClick">
        <img class="cate-icon img-position" src="//image.zlketang.com/public/news/images/reply_msg_quick/send-img.png" />
        <span>上传图片</span>
      </div>
      <div :class="[chooseReply ? 'send-quick-msg-active' : 'send-quick-msg','flex-center','margin-cate-send']" @click="chooseQuickMsg">
        <img class="cate-icon img-position" v-if="chooseReply" src="//image.zlketang.com/public/news/images/reply_msg_quick/reply-msg-active.png" />
        <img class="cate-icon img-position" v-else src="//image.zlketang.com/public/news/images/reply_msg_quick/reply-msg-default.png" />
        <span>常用语</span>
      </div>
      <!-- <el-popover placement="top" width="400" trigger="click">
        <div class="emojis">
          <div v-for="item in emojiName" class="emoji" :key="item" @click="chooseEmoji(item)">
            <img :src="emojiUrl + emojiMap[item]" style="width:30px;height:30px" />
          </div>
        </div>
        <i class="iconfont icon-smile" slot="reference" title="发表情"></i> 
      </el-popover>-->
      <!-- <i
        class="iconfont icon-tupian"
        title="发图片"
        @click="handleSendImageClick"
      ></i>
      <i class="el-icon-chat-dot-square" :style="{color:chooseReply ? '#5cb6ff' : '#606266', 'font-size':'24px'}" @click="chooseQuickMsg"></i> -->
      <!-- 隐藏部分功能 -->
      <!-- <i
        class="el-icon-camera"
        title="发视频"
        @click="handleSendVideoClick"
      ></i> -->
      <!-- <i
        class="iconfont icon-wenjian"
        title="发文件"
        @click="handleSendFileClick"
      ></i> -->
      <!-- <i class="iconfont icon-zidingyi" title="发自定义消息" @click="sendCustomDialogVisible = true"></i> -->
      <!-- <i class="el-icon-video-camera" v-if="currentConversationType === 'C2C'&& toAccount !== userID" title="视频通话" @click="videoCall"></i> -->
      <!-- <i
        class="el-icon-chat-line-round"
        title="聊天记录"
        @click="showHistory"
      ></i> -->
    </div>
    <el-dialog
      title="发自定义消息"
      :visible.sync="sendCustomDialogVisible"
      width="30%"
    >
      <el-form label-width="100px">
        <el-form-item label="data">
          <el-input v-model="form.data"></el-input>
        </el-form-item>
        <el-form-item label="description">
          <el-input v-model="form.description"></el-input>
        </el-form-item>
        <el-form-item label="extension">
          <el-input v-model="form.extension"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="sendCustomDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="sendCustomMessage">确 定</el-button>
      </span>
    </el-dialog>
    <el-popover
      trigger="manual"
      v-model="showAtGroupMember"
      placement="top"
      style="max-height: 500px; overflow-y: scroll"
    >
      <el-radio-group
        v-model="atUserID"
        style="display: flex; flex-decoration: column"
        v-for="member in showMemberList"
        :key="member.userID"
        @change="handleSelectAtUser"
      >
        <el-radio :label="member.userID">
          {{ member.nameCard || member.nick || member.userID }}
        </el-radio>
      </el-radio-group>
    </el-popover>
    <div class="bottom quick-msg-wrap" v-if="chooseReply">
      <div class="quick-msg-item" @click="chooseReplyMsg(item.content)" v-for="item in quickReplyList" :key="item.id">{{item.content}}</div>
    </div>
    <div class="bottom" v-else>
      <textarea
        ref="text-input"
        rows="4"
        resize="false"
        v-model="messageContent"
        class="text-input"
        @focus="focus = true"
        @blur="focus = false"
        @keydown="handleKeyDown"
        @keydown.enter.exact.prevent="handleEnter"
        @keyup.ctrl.enter.prevent.exact="handleLine"
        @keydown.up.stop.exact="handleUp"
        @keydown.down.stop.exact="handleDown"
        @keydown.delete.exact="handleDelete"
        @keydown.shift.left="handleShiftLeft"
        @keydown.shift.right="handleShiftRight"
        @keydown.shift.up="handleShiftUp"
        @keydown.shift.down="handleShiftDown"
        @input="inputMsg"
        @compositionstart="spellStart"
        @compositionend="spellEnd"
        @select="handleSelect"
      ></textarea>
      <el-tooltip
        class="item"
        effect="dark"
        content="按Enter发送消息，Ctrl+Enter换行"
        placement="left-start"
      >
        <div class="btn-send" @click="handleEnter">
          <div class="tim-icon-send"></div>
        </div>
      </el-tooltip>
    </div>
    <input
      type="file"
      id="imagePicker"
      ref="imagePicker"
      accept=".jpg, .jpeg, .png, .gif"
      @change="sendImage"
      style="display: none"
    />
    <input
      type="file"
      accept=".pdf"
      id="filePicker"
      ref="filePicker"
      @change="sendFile"
      style="display: none"
    />
    <input
      type="file"
      id="videoPicker"
      ref="videoPicker"
      @change="sendVideo"
      style="display: none"
      accept=".mp4"
    />
    <ul
      v-show="isShowMenberBox"
      class="member-box userMemberList"
      ref="memberBox"
    >
      <li
        v-for="(item, index) in showMemberList"
        :key="index"
        class="member-box-item userMemberList"
        :class="
          memberListLight.userID === item.userID ? 'member-box-item-light' : ''
        "
        @click="atUser(item)"
      >
        <img
          :src="item.avatar"
          alt
          class="member-box-img userMemberList"
          v-if="!item.isAtALL"
        />
        <div class="member-box-nick userMemberList">{{ item.nick }}</div>
      </li>
    </ul>
  </div>
</template>

<script>
import { mapGetters, mapState } from 'vuex'
import {
  Form,
  FormItem,
  Input,
  Dialog,
  Popover,
  RadioGroup,
  Radio,
  Tooltip
} from 'element-ui'
import { emojiMap, emojiName, emojiUrl } from '../../utils/emojiMap'
import studyCenter from '@/api/studyCenter'

export default {
  name: 'message-send-box',
  props: ['scrollMessageListToButtom'],
  components: {
    ElInput: Input,
    ElForm: Form,
    ElFormItem: FormItem,
    ElDialog: Dialog,
    ElPopover: Popover,
    ElRadioGroup: RadioGroup,
    ElRadio: Radio,
    ElTooltip: Tooltip
  },
  data() {
    return {
      colors: ['#99A9BF', '#F7BA2A', '#FF9900'],
      messageContent: '',
      isSendCustomMessage: false,
      sendCustomDialogVisible: false,
      surveyDialogVisible: false,
      form: {
        data: '',
        description: '',
        extension: ''
      },
      rate: 5, // 评分
      suggestion: '', // 建议
      file: '',
      emojiMap: emojiMap,
      emojiName: emojiName,
      emojiUrl: emojiUrl,
      showAtGroupMember: false,
      atUserID: '',
      focus: false,
      //用于渲染的成员列表
      showMemberList: [],
      //当前高亮的成员info
      memberListLight: {},
      //@的用户列表
      atUserInfo: [],
      //当前光标位置
      cursorPosNow: '',

      //@用户弹窗出现的时候，接着输入的字符串
      atStr: '',

      //文本域的window.selection()
      selectionFunc: '',
      //当前选中的文本
      curSelectText: '',
      //当前选取，光标位置
      curSelectPos: 0,

      //输入@后展示当前群里所有的用户，以供选择
      isShowMenberBox: false,
      //当前是否是中文拼写状态
      isSpellState: false,
      //是否是右键@
      isRightKeyAt:false,
      //选择回复快捷语
      chooseReply: false,
      //快捷语回复列表
      quickReplyList: []
    }
  },
  computed: {
    ...mapGetters(['toAccount', 'currentConversationType']),
    ...mapState({
      memberList: (state) => state.group.currentMemberList,
      userID: (state) => state.user.userID,
      IsShowHistory: (state) => state.conversation.IsShowHistory,
      currentCustomOptions: (state) => state.conversation.currentCustomOptions,
      currentUserProfile: (state) => state.user.currentUserProfile,
      userInfo: (state) => state.user,
      currentConversation: (state) => state.conversation.currentConversation
    }),
    allMemberList() {
      //在成员列表最头部添加全体成员
      var arr = JSON.parse(JSON.stringify(this.memberList))
      arr.unshift({ nick: '全体成员', userID: '0', isAtALL: true })
      return arr
    }
  },
  mounted() {
    this.$refs['text-input'].addEventListener('paste', this.handlePaste) //监听粘贴事件
    this.$refs['text-input'].addEventListener('beforecut', this.handleCut) //监听剪切事件
    this.$bus.$on('reEditMessage', this.reEditMessage)
    this.$bus.$on('empty-message', () => {
      this.messageContent = ''
      this.atUserInfo = []
      this.atStr = ''
    })
    //右键点击@用户
    this.$bus.$on('rightKeyClick',(item) => {
      this.isRightKeyAt = true
      let pos = this.getCursortPosition(this.$refs['text-input'])
      this.messageContent = this.messageContent.slice(0,pos) + '@' + this.messageContent.slice(pos)
      this.inputMsg({data:'@'})
      this.atUser(item.member)
    })
    this.globalClick(this.clickPage)
    this.showMemberList = JSON.parse(JSON.stringify(this.allMemberList))
    this.selectionFunc = window.getSelection()
  },
  beforeDestroy() {
    this.$refs['text-input'].removeEventListener('paste', this.handlePaste)
  },
  methods: {
    //显示历史消息
    showHistory() {
      this.$store.commit('updateHistoryConversation')
    },
    reEditMessage(payload) {
      this.messageContent = payload
    },
    handleSelectAtUser() {
      this.messageContent += this.atUserID + ' '
      this.showAtGroupMember = false
    },
    handleUp(e) {
      if (this.isShowMenberBox) {
        e.preventDefault() //@用户框打开的时候，禁用掉默认事件（在文本框中移动事件），向上箭头，改变当前列表中高亮的用户
        var memberBoxDom = this.$refs.memberBox
        var menberListLen = this.showMemberList.length
        for (var i = 0; i < menberListLen; i++) {
          if (this.showMemberList[i].userID === this.memberListLight.userID) {
            if (i - 1 < 0) {
              //当前高亮的是列表中第一个用户
              return
            }
            this.memberListLight = this.showMemberList[i - 1] //当前高亮的用户
            if (i < menberListLen - 5) {
              //控制滚动条高度，当前高亮用户小于用户总数-5，滚动条高度减小
              memberBoxDom.scrollTop -= 22
            }
            return
          }
        }
      }
    },
    handleDown(e) {
      if (this.isShowMenberBox) {
        e.preventDefault() //@用户框打开的时候，禁用掉默认事件（在文本框中移动事件），向下箭头，改变当前列表中高亮的用户
        var memberBoxDom = this.$refs.memberBox
        var menberListLen = this.showMemberList.length
        for (var i = 0; i < menberListLen; i++) {
          if (i + 1 === menberListLen) {
            //当前高亮的是列表中最后一个用户
            return
          }
          if (this.showMemberList[i].userID === this.memberListLight.userID) {
            this.memberListLight = this.showMemberList[i + 1] //当前高亮的用户
            if (i > 5) {
              //控制滚动条的高度，当前高亮用户大于5，滚动条高度减小
              memberBoxDom.scrollTop += 22
            }
            return
          }
        }
      }
    },
    handleKeyDown() {
      if (this.curSelectText) {
        this.curSelectText = ''
      }
    },
    handleEnter() {
      if (this.currentConversationType === 'C2C') {
        //单聊
        this.sendTextMessage()
        return
      }

      if (this.currentConversationType === 'GROUP') {
        //群聊

        if (this.isShowMenberBox) {
          //如果当前用户选择列表是打开的，那么，按下enter键代表选择当前的@用户
          this.atUser(this.memberListLight)
          return
        }

        if (this.atUserInfo && this.atUserInfo.length > 0) {
          //有@信息
          this.sendAtUserMsg()
        } else {
          this.sendTextMessage()
        }
      }
    },
    handleLine() {
      this.messageContent += '\n'
    },
    //文本选中事件
    handleSelect() {
      this.curSelectText = this.selectionFunc.toString()
      this.curSelectPos = this.getCursortPosition(this.$refs['text-input'])
    },
    //粘贴事件
    handlePaste(e) {
      // if (this.currentConversationType === 'C2C') return
      var that = this
      var clipboardData = e.clipboardData || window.clipboardData
      var i = 0
      var items
      var item
      var types
      // if (
      //   clipboardData &&
      //   clipboardData.items &&
      //   clipboardData.items.length > 0
      // ) {
      //   var item = clipboardData.items[0]   //获取最近一次粘贴的信息
      //   if(item.kind === 'string') {        //最近一次粘贴的信息是字符串时
      //     item.getAsString(function(str) {    //获取到粘贴字符串，执行输入操作
      //        that.inputMsg({data:str})
      //     })
      //   }
      // }
      if (clipboardData) {
        items = clipboardData.items
        if (!items) {
          return
        }
        item = items[0]
        // 保存在剪贴板中的数据类型
        types = clipboardData.types || []
        for (; i < types.length; i++) {
          if (types[i] === 'Files') {
            item = items[i]
            break
          }
        }
        // 判断是否为图片数据
        if (item && item.kind === 'file' && item.type.match(/^image\//i)) {
          // 读取该图片
          that.imgReader(item)
        } else {
          item.getAsString(function(str) {
            that.inputMsg({ data: str })
          })
        }
      }
    },
    getType(o) {
      return Object.prototype.toString
        .call(o)
        .toLowerCase()
        .replace(/[\[\]]/g, '')
        .split(' ')[1]
    },
    imgReader: function(item) {
      var _this = this
      var file = item.getAsFile()
      var reader = new FileReader()
      // 读取文件后将其显示在网页中
      reader.onload = function(e) {
        var base64Str = e.target.result
        var fileObj = _this.dataURLtoFile(base64Str, 'test.png')
        _this.sendImage(fileObj)
      }
      // 读取文件
      reader.readAsDataURL(file)
    },
    //将base64转换为文件
    dataURLtoFile(dataurl, filename) {
      var arr = dataurl.split(','),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n)
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
      }
      return new File([u8arr], filename, {
        type: mime
      })
    },
    //剪切事件
    handleCut() {
      //  剪切时触发
      if (this.currentConversationType === 'C2C') return
      var selectText = this.selectionFunc.toString()
      if (selectText.length > 0) {
        //当前是否有选中的文本
        this.selectDeal(selectText)
        return
      }
    },
    //点击删除按钮
    handleDelete() {
      if (this.currentConversationType === 'C2C') return
      var selectText = this.selectionFunc.toString()
      if (selectText.length > 0) {
        //当前是否是选中删除
        this.selectDeal(selectText)
        return
      }
      if (this.isShowMenberBox) {
        //@弹窗出现时候的删除逻辑
        var pos = this.getCursortPosition(this.$refs['text-input']) //获取当前光标位置，此时位置是删除前光标的位置
        //判断删除时候，光标的位置在@之前或者在@输入昵称之后
        if (
          this.cursorPosNow > pos ||
          pos > this.cursorPosNow + this.atStr.length
        ) {
          //将 this.atStr的长度加在之后的@用户的起止位置上
          this.isShowMenberBox = false
          this.atStr = ''
          this.normalDeleteText(pos)
        } else {
          var diff_pos = pos - this.cursorPosNow - 1 //计算删除后光标位置到@距离
          if (diff_pos > -1) {
            this.atStr = this.atStr.split('') //计算当前@输入的文本，插入的地方
            this.atStr.splice(diff_pos - 2, 1)
            this.atStr = this.atStr.join('')
            var memberLen = this.allMemberList.length
            this.showMemberList = []
            for (var k = 0; k < memberLen; k++) {
              //模糊匹配筛选
              var reg = new RegExp(this.atStr, 'g')
              if (reg.test(this.allMemberList[k].nick)) {
                this.showMemberList.push(this.allMemberList[k])
              }
            }
          }
          if (diff_pos >= -1) {
            //@出现时，删除同样要改变，之后已@用户起止位置
            var userIndex = this.atUserInfo.length - 1
            for (var i = userIndex; i >= 0; i--) {
              var item = this.atUserInfo[i]
              //在当前@用户名称之前进行删除，修改当前用户名称的起止位置
              if (item.start < this.cursorPosNow) {
                break
              } else {
                item.start = item.start - 1
                item.end = item.end - 1
              }
            }
          }
          if (this.showMemberList.length === 0 || diff_pos === -1) {
            //模糊搜索为空,或者删除的是@的时候
            //当未筛选到匹配用户时
            this.isShowMenberBox = false

            this.showMemberList = JSON.parse(JSON.stringify(this.allMemberList))
            this.atStr = ''
          }
          if (this.showMemberList.length > 0) {
            //筛选到用户之后，默认高亮当前第一个，并且滚动条置顶
            var memberBoxDom = this.$refs.memberBox
            this.memberListLight = this.showMemberList[0]
            memberBoxDom.scrollTop = 0
          }
        }
        return
      }
      if (!this.atUserInfo || this.atUserInfo.length === 0) return //没有@的人的时候，不进行后续判断
      this.normalDeleteText()
    },
    //禁用shift+left的组合键默认事件
    handleShiftLeft(e) {
      e.preventDefault()
    },
    //禁用shift+right的组合键默认事件
    handleShiftRight(e) {
      e.preventDefault()
    },
    //禁用shift+up的组合键默认事件
    handleShiftUp(e) {
      e.preventDefault()
    },
    //禁用shift+down的组合键默认事件
    handleShiftDown(e) {
      e.preventDefault()
    },
    //@弹窗未弹出时候的正常删除逻辑
    normalDeleteText(_pos) {
      var pos
      if (!_pos) {
        pos = this.getCursortPosition(this.$refs['text-input']) //获取当前光标位置
      } else {
        pos = _pos
      }
      if (pos === 0) return
      var userLen = this.atUserInfo.length
      var deleteEnd
      var deleteNickLen
      var strLen = this.atStr.length
      for (var i = userLen - 1; i >= 0; i--) {
        //循环当前已@的人的信息
        var item = this.atUserInfo[i]
        if (item.end === pos) {
          //当前删除时，光标正好在@用户的空格后面，需要将@用户全部删除
          this.messageContent = this.messageContent + ' ' //在当前的文本后加上空格，下面在删除整个@的用户后，光标默认回到文本最后，还会执行一次默认的删除操作
          deleteEnd = item.end //记录当前删除的用户的结束位置
          var itemLen = item.nickName.length
          deleteNickLen = itemLen + 1 //记录当前删除用户的昵称+@（空格不列入其中，倒序循环，最开始就会-1）
          this.messageContent =
            this.messageContent.slice(0, item.start) +
            this.messageContent.slice(item.end, this.messageContent.length + 1) //截取当前文本域中除了删除用户的昵称外的其他文本进行拼接

          this.atUserInfo.splice(i, 1) //从数组中删除当前@用户数据

          setTimeout(() => {
            this.cursorPosNow = item.start
            this.setCaretPosition(this.$refs['text-input'], this.cursorPosNow) //重置光标位置
            var userDealLen = this.atUserInfo.length - 1
            for (var j = userDealLen; j >= 0; j--) {
              //倒序循环删除@用户后的其他用户数据，对他们的起止位置进行更改
              var itemj = this.atUserInfo[j]
              if (itemj.start + 1 >= deleteEnd) {
                itemj.start = itemj.start - deleteNickLen
                itemj.end = itemj.end - deleteNickLen
              } else {
                return
              }
            }
          }, 0)
          return
        } else if (item.start < pos && item.end > pos) {
          this.atUserInfo.splice(i, 1) //在当前@的用户昵称中删除文字，当前@用户的结构被破坏，从数组中删除当前@用户数据
        } else if (item.start >= pos) {
          //正常删除操作
          item.start = item.start - strLen - 1
          item.end = item.end - strLen - 1
        }
      }
    },
    //修改文本框文字
    inputMsg(e) {
      if (
        this.isSpellState ||
        !e.data ||
        this.currentConversationType === 'C2C'
      )
        return //正在拼写状态或者输入为空或不是群聊

      if (this.curSelectText) {
        //是否是选中输入
        var len = e.data.length
        this.selectDeal(this.curSelectText, len)
        return
      }

      if (this.isShowMenberBox) {
        //@弹窗当前显示的时候
        this.atUserDealInfo(e)
        return
      }
      this.normalInputText(e) //未显示弹窗，正常输入
    },
    //@弹窗未弹出时候的正常输入逻辑
    normalInputText(e) {
      var pos = this.getCursortPosition(this.$refs['text-input'])
      if (e.data === '@' && !this.isShowMenberBox && !this.isRightKeyAt) {
        var memberBoxDom = this.$refs.memberBox
        this.showMemberList = JSON.parse(JSON.stringify(this.allMemberList))
        this.cursorPosNow = pos
        this.isShowMenberBox = true
        this.memberListLight = this.showMemberList[0]
        memberBoxDom.scrollTop = 0
      }
      if(this.isRightKeyAt){  //右键@用户，不弹窗，但是需要记录位置
        this.cursorPosNow = pos + 1
        this.isRightKeyAt = false
      }
      var spellLen = e.data.length
      var userIndex = this.atUserInfo.length - 1
      for (var i = userIndex; i >= 0; i--) {
        var atUserInfoItem = this.atUserInfo[i]
        if (
          atUserInfoItem.start < pos - spellLen &&
          atUserInfoItem.end > pos - spellLen
        ) {
          //在当前@的用户昵称中添加文字，当前@用户的结构被破坏，从数组中删除当前@用户数据
          this.atUserInfo.splice(i, 1)
        } else if (atUserInfoItem.start >= pos - spellLen) {
          //在当前@用户名称之前进行输入，修改当前用户名称的起止位置
          atUserInfoItem.start = atUserInfoItem.start + spellLen
          atUserInfoItem.end = atUserInfoItem.end + spellLen
        }
      }
    },
    //监听拼写开始事件
    spellStart() {
      if (this.currentConversationType === 'C2C') return //不是群聊
      this.isSpellState = true
    },
    //监听拼写结束事件
    spellEnd(e) {
      if (!e.data || this.currentConversationType === 'C2C') return //输入为空或不是群聊
      this.isSpellState = false
      if (this.curSelectText) {
        //是否是选中输入
        var len = e.data.length
        this.selectDeal(this.curSelectText, len)
        return
      }
      if (this.isShowMenberBox) {
        this.atUserDealInfo(e)
        return
      }
      this.normalInputText(e)
    },
    //输入、拼写、粘贴时，@弹窗显示的时候的模糊匹配以及相应@用户起止值的修改
    atUserDealInfo(e) {
      var spellData = e.data //如果正常输入，spellData长度一定是1，也可以是粘贴或者是拼写，则字符串长度不定
      var spellLen = e.data.length
      var pos = this.getCursortPosition(this.$refs['text-input'])

      //判断输入的时候，光标的位置在@之前或者在@输入昵称之后
      if (
        //在当前@的用户之前或者之后进行输入操作
        this.cursorPosNow >= pos ||
        pos > this.cursorPosNow + this.atStr.length + spellLen
      ) {
        this.isShowMenberBox = false
        this.normalInputText(e) //正常输入
        this.atStr = '' //当
      } else {
        //此时diff_pos一定>=1
        var diff_pos = pos - this.cursorPosNow //计算当前光标位置到当前@的距离

        this.atStr = this.atStr.split('') //将当前输入的字符，插入到atStr中对应的位置
        this.atStr.splice(diff_pos - 1, 0, spellData)
        this.atStr = this.atStr.join('')
        var memberLen = this.allMemberList.length
        this.showMemberList = []
        for (var i = 0; i < memberLen; i++) {
          //模糊匹配筛选@用户
          var reg = new RegExp(this.atStr, 'g')
          if (reg.test(this.allMemberList[i].nick)) {
            this.showMemberList.push(this.allMemberList[i])
          }
        }
        //每一次输入，都要修改已@用户的起止位置
        var userIndex = this.atUserInfo.length - 1
        for (var j = userIndex; j >= 0; j--) {
          var item = this.atUserInfo[j]
          //在已@用户名称之前进行输入，修改用户名称的起止位置
          if (item.start >= this.cursorPosNow) {
            item.start = item.start + spellLen
            item.end = item.end + spellLen
          } else {
            break
          }
        }

        if (this.showMemberList.length === 0) {
          //当未筛选到匹配用户时
          this.isShowMenberBox = false
          this.showMemberList = JSON.parse(JSON.stringify(this.allMemberList))
          this.atStr = ''
        } else {
          //筛选到用户之后，默认高亮当前第一个，并且滚动条置顶
          var memberBoxDom = this.$refs.memberBox
          this.memberListLight = this.showMemberList[0]
          memberBoxDom.scrollTop = 0
        }
      }
    },
    //选中之后的删除、剪切、粘贴、输入,第二个参数是选中粘贴和输入的文本的长度
    selectDeal(text, len) {
      var pos, selectEnd
      var selectLen = text.length //当前选取文字的长度
      this.atStr = ''
      this.isShowMenberBox = false
      var userLen = this.atUserInfo.length
      var inputLen = 0
      if (len) {
        inputLen = len
        pos = this.curSelectPos
        selectEnd = pos + selectLen //选区结束位置
        this.curSelectText = ''
      } else {
        pos = this.getCursortPosition(this.$refs['text-input']) //获取当前光标位置，选中文本的时候，光标位置永远都是选中文本开始的那个位置
        selectEnd = pos + selectLen //选区结束位置
      }
      for (var i = userLen - 1; i >= 0; i--) {
        //循环当前已@的人的信息
        var item = this.atUserInfo[i]

        if (item.end <= pos) {
          //已@用户的结束位置>=选区开始位置，则当前@的用户在当前删除的文本的前面
          break
        } else if (item.start >= selectEnd) {
          //已@用户的开始位置>=选区结束位置，则当前@的用户在当前删除的文本的后面，修改起止位置
          item.start = item.start - selectLen + inputLen
          item.end = item.end - selectLen + inputLen
        } else {
          //其他情况，包括：选取的起止位置在@用户的起止位置中间、选区包含整个@用户、@用户包含选区，这些情况直接在@用户信息数组中删除该用户信息
          this.atUserInfo.splice(i, 1)
        }
      }
    },
    dropHandler(e) {
      e.preventDefault()
      var file = e.dataTransfer.files[0]
      var message = {}
      if (file.type === 'video/mp4') {
        message = this.tim.createVideoMessage({
          to: this.toAccount,
          conversationType: this.currentConversationType,
          payload: {
            file: file
          },
          onProgress: (percent) => {
            this.$set(message, 'progress', percent) // 手动给message 实例加个响应式属性: progress
          }
        })
      } else {
        message = this.tim.createFileMessage({
          to: this.toAccount,
          conversationType: this.currentConversationType,
          payload: {
            file: file
          },
          onProgress: (percent) => {
            this.$set(message, 'progress', percent) // 手动给message 实例加个响应式属性: progress
          }
        })
      }
      this.$store.commit('pushCurrentMessageList', message)
      var options = this.currentCustomOptions
       
      options.offlinePushInfo.description = `${this.currentUserProfile.nick}:${this.messageContent}`
      this.tim
        .sendMessage(message, options)
        .then(() => {
          this.$refs.videoPicker.value = null
        })
        .catch((imError) => {
          this.$store.commit('showMessage', {
            message: imError.message,
            type: 'error'
          })
        })
    },
    sendAtUserMsg() {
      //遍历at信息，查看是否有@全体成员
      var isAlertAll = '0'
      var atUserLen = this.atUserInfo.length
      for (var i = 0; i < atUserLen; i++) {
        if (this.atUserInfo[i].isAtALL) {
          isAlertAll = '1'
          this.atUserInfo = []
          break
        }
      }
      //当@了用户的时候，发送自定义消息
      var obj = JSON.stringify({
        custom_way: 'text_alter',
        text: this.messageContent,
        memberList: this.atUserInfo,
        fromUserId: this.userInfo.currentUserProfile.userID,
        fromNickName: this.userInfo.currentUserProfile.nick,
        className: this.currentConversation.groupProfile.introduction,
        is_alter_all: isAlertAll,
        groupId: this.toAccount
      })
      const message = this.tim.createCustomMessage({
        to: this.toAccount,
        conversationType: this.currentConversationType,
        payload: {
          data: obj,
          description: '',
          extension: ''
        }
      })
      this.$store.commit('pushCurrentMessageList', message)
      this.$bus.$emit('scroll-bottom')
      var options = this.currentCustomOptions
      
      options.offlinePushInfo.description = `${this.currentUserProfile.nick}:${this.messageContent}`
      this.tim.sendMessage(message, options).catch((error) => {
        this.$store.commit('showMessage', {
          type: 'error',
          message: error.message
        })
      })
      this.messageContent = ''
      this.atUserInfo = []
      this.atStr = ''
    },
    sendTextMessage() {
      if (
        this.messageContent === '' ||
        this.messageContent.trim().length === 0
      ) {
        this.messageContent = ''
        this.$store.commit('showMessage', {
          message: '不能发送空消息哦！',
          type: 'info'
        })
        return
      }
      const message = this.tim.createTextMessage({
        to: this.toAccount,
        conversationType: this.currentConversationType,
        payload: { text: this.messageContent }
      })
      this.$store.commit('pushCurrentMessageList', message)
      this.$bus.$emit('scroll-bottom')
      // var options = this.currentCustomOptions ||{}
      // options.offlinePushInfo.description = `${this.currentUserProfile.nick}:${this.messageContent}`
      this.tim.sendMessage(message).catch((error) => {
        this.$store.commit('showMessage', {
          type: 'error',
          message: error.message
        })
      })
      this.messageContent = ''
    },
    sendCustomMessage() {
      
      if (
        this.form.data.length === 0 &&
        this.form.description.length === 0 &&
        this.form.extension.length === 0
      ) {
        this.$store.commit('showMessage', {
          message: '不能发送空消息',
          type: 'info'
        })
        return
      }
      const message = this.tim.createCustomMessage({
        to: this.toAccount,
        conversationType: this.currentConversationType,
        payload: {
          data: this.form.data,
          description: this.form.description,
          extension: this.form.extension
        }
      })
      this.$store.commit('pushCurrentMessageList', message)
      this.tim.sendMessage(message).catch((error) => {
        this.$store.commit('showMessage', {
          type: 'error',
          message: error.message
        })
      })
      Object.assign(this.form, {
        data: '',
        description: '',
        extension: ''
      })
      this.sendCustomDialogVisible = false
    },
    random(min, max) {
      return Math.floor(Math.random() * (max - min + 1) + min)
    },
    sendSurvey() {
      
      const message = this.tim.createCustomMessage({
        to: this.toAccount,
        conversationType: this.currentConversationType,
        payload: {
          data: 'survey',
          description: String(this.rate),
          extension: this.suggestion
        }
      })
      this.$store.commit('pushCurrentMessageList', message)
      Object.assign(this.form, {
        data: '',
        description: '',
        extension: ''
      })
      this.tim
        .sendMessage(message)
        .then(() => {
          Object.assign(this, {
            rate: 5,
            suggestion: ''
          })
        })
        .catch((error) => {
          this.$store.commit('showMessage', {
            type: 'error',
            message: error.message
          })
        })
      this.surveyDialogVisible = false
    },
    chooseEmoji(item) {
      this.messageContent += item
    },
    handleSendImageClick() {
      this.$refs.imagePicker.click()
    },
    handleSendFileClick() {
      this.$refs.filePicker.click()
    },
    handleSendVideoClick() {
      this.$refs.videoPicker.click()
    },
    videoCall() {
      this.$bus.$emit('video-call')
    },
    // 可传参数：file为file对象
    sendImage(file) {
      let fileType = this.getType(file)
      const message = this.tim.createImageMessage({
        to: this.toAccount,
        conversationType: this.currentConversationType,
        payload: {
          file: fileType === 'file' ? file : document.getElementById('imagePicker') // 或者用event.target
        },
        onProgress: (percent) => {
          this.$set(message, 'progress', percent) // 手动给message 实例加个响应式属性: progress
        }
      })
      this.$store.commit('pushCurrentMessageList', message)
      var options = this.currentCustomOptions
      
      options.offlinePushInfo.description = `${this.currentUserProfile.nick}:[图片]`
      this.tim
        .sendMessage(message, options)
        .then(() => {
          this.$refs.imagePicker.value = null
        })
        .catch((imError) => {
          this.$store.commit('showMessage', {
            message: imError.message,
            type: 'error'
          })
        })
    },
    sendFile() {
      const message = this.tim.createFileMessage({
        to: this.toAccount,
        conversationType: this.currentConversationType,
        payload: {
          file: document.getElementById('filePicker') // 或者用event.target
        },
        onProgress: (percent) => {
          this.$set(message, 'progress', percent) // 手动给message 实例加个响应式属性: progress
        }
      })
      this.$store.commit('pushCurrentMessageList', message)
      var options = this.currentCustomOptions
     
      options.offlinePushInfo.description = `${this.currentUserProfile.nick}:[文件]`
      this.tim
        .sendMessage(message, options)
        .then(() => {
          this.$refs.filePicker.value = null
        })
        .catch((imError) => {
          this.$store.commit('showMessage', {
            message: imError.message,
            type: 'error'
          })
        })
    },
    sendVideo() {
      const message = this.tim.createVideoMessage({
        to: this.toAccount,
        conversationType: this.currentConversationType,
        payload: {
          file: document.getElementById('videoPicker') // 或者用event.target
        },
        onProgress: (percent) => {
          this.$set(message, 'progress', percent) // 手动给message 实例加个响应式属性: progress
        }
      })
      this.$store.commit('pushCurrentMessageList', message)
      var options = this.currentCustomOptions
      
      options.offlinePushInfo.description = `${this.currentUserProfile.nick}:[视频]`
      this.tim
        .sendMessage(message, options)
        .then(() => {
          this.$refs.videoPicker.value = null
        })
        .catch((imError) => {
          this.$store.commit('showMessage', {
            message: imError.message,
            type: 'error'
          })
        })
    },
    //页面触发点击事件的时候，如果此时@弹窗显示，并且点击的不是该弹窗，则隐藏弹窗
    clickPage(e) {
      if (this.curSelectText) {
        this.curSelectText = ''
      }
      if (this.isShowMenberBox && !/userMemberList/.test(e.target.className)) {
        this.isShowMenberBox = false
      }
    },
    // 获取光标位置
    getCursortPosition(ele) {
      //获取光标位置函数
      var CaretPos = 0
      // 兼容IE
      if (document.selection) {
        ele.focus() // 获取焦点
        var Sel = document.selection.createRange() // 创建选定区域
        Sel.moveStart('character', -ele.value.length) // 移动开始点到最左边位置
        CaretPos = Sel.text.length // 获取当前选定区的文本内容长度
      }
      // 兼容Firefox
      else if (ele.selectionStart || ele.selectionStart == '0') {
        CaretPos = ele.selectionStart // 获取选定区的开始点
      }
      return CaretPos
    },
    // 设置光标位置
    setCaretPosition(ele, pos) {
      if (ele.setSelectionRange) {
        // IE支持
        ele.focus()
        ele.setSelectionRange(pos, pos)
      } else if (ele.createTextRange) {
        //火狐支持
        var range = ele.createTextRange()
        range.collapse(true)
        range.moveEnd('character', pos)
        range.moveStart('character', pos)
        range.select()
      }
    },
    //选取@的用户
    atUser(item) {
      this.isShowMenberBox = false
      var len = this.messageContent.length
      var nickLen = item.nick.length + 1
      var strLen = this.atStr.length
      this.messageContent =
        this.messageContent.slice(0, this.cursorPosNow) +
        item.nick +
        ' ' +
        this.messageContent.slice(this.cursorPosNow + this.atStr.length, len)

      //若不是用延时，浏览器的默认事件会将其覆盖掉
      setTimeout(() => {
        this.cursorPosNow = this.cursorPosNow + nickLen
        this.setCaretPosition(this.$refs['text-input'], this.cursorPosNow)
      }, 0)

      var userIndex = this.atUserInfo.length - 1
      for (var i = userIndex; i >= 0; i--) {
        var atUserInfoItem = this.atUserInfo[i]
        //在当前@用户名称之前进行输入，修改当前用户名称的起止位置
        if (atUserInfoItem.start < this.cursorPosNow) {
          break
        } else {
          atUserInfoItem.start = atUserInfoItem.start + nickLen - strLen
          atUserInfoItem.end = atUserInfoItem.end + nickLen - strLen
        }
      }
      var obj = {
        nickName: item.nick,
        userId: item.userID,
        start: this.cursorPosNow - 1,
        end: this.cursorPosNow + nickLen
      }
      if (item.isAtALL) {
        obj.isAtALL = item.isAtALL
      }
      this.atStr = ''
      this.atUserInfo.push(obj)
      this.atUserInfo.sort((a, b) => {
        //排序，便于循环时倒序操作
        return a.start - b.start
      })
    },
    //获取快捷语回复列表
    getQuickList() {
      studyCenter.quickReplyMsg().then(res=>{
        this.quickReplyList = res.data.list
      })
    },
    //选择快捷语
    chooseQuickMsg() {
      this.chooseReply = !this.chooseReply
    },
    //确认快捷语
    chooseReplyMsg(content) {
      this.chooseReply = false
      this.messageContent = content
    }
  },
  created() {
    this.getQuickList()
  },
}
</script>

<style lang="stylus" scoped>
#message-send-box-wrapper {
  position: relative;
  box-sizing: border-box;
  padding: 3px 20px 20px 20px;
  user-select: none;
}

.emojis {
  height: 160px;
  box-sizing: border-box;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  overflow-y: scroll;
}

.emoji {
  height: 40px;
  width: 40px;
  box-sizing: border-box;
}

.send-header-bar {
  box-sizing: border-box;
  padding: 3px 0 0 0;
}

.send-header-bar i {
  cursor: pointer;
  font-size: 24px;
  color: gray;
  margin: 0 12px 0 0;
}

.send-header-bar i:hover {
  color: $black;
}

textarea {
  resize: none;
}

.text-input {
  position: relative;
  font-size: 16px;
  width: 100%;
  box-sizing: box-sizing;
  border: none;
  outline: none;
  background-color: transparent;
}

.block {
  padding: 10px 0;
  display: flex;
  align-items: center;
}

.bottom {
  margin-top: 8px;
  position: relative;
  border-top: 1px solid #D9D9D9;
  .btn-send {
    cursor: pointer;
    position: absolute;
    color: $primary;
    font-size: 30px;
    right: 0;
    bottom: -5px;
    padding: 6px 6px 4px 4px;
    border-radius: 50%;
  }
}

.member-box {
  position: absolute;
  top: -156px;
  left: 5px;
  width: 160px;
  height: 156px;
  padding: 0;
  margin: 0;
  overflow: auto;
  background-color: #fff;
  font-size: 12px;
  border-radius: 6px;
  box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.15);

  .member-box-item {
    display: flex;
    justify-content: flex-start;
    align-item: center;
    padding: 3px 5px;
    list-style: none;
    cursor: default;

    .member-box-img {
      width: 16px;
      height: 16px;
      margin-right: 10px;
      border-radius: 50%;
    }

    .member-box-nick {
      white-space: nowrap;
      text-overflow: ellipsis;
      overflow: hidden;
    }
  }

  .member-box-item:hover {
    background-color: #5cadff;
    color: #fff;
  }

  .member-box-item-light {
    background-color: #5cadff;
    color: #fff;
  }
}
.send-img {
  display: inline-block;
  width: 96px;
  height: 32px;
  background: #F5F5F5;
  border: 1px solid #D9D9D9;
  color: #8C8C8C;
  font-size: 14px;
  font-weight: 400;
  line-height: 32px;
  cursor: pointer;
  .cate-icon {
    display: inline-block;
    width: 20px;
    height: 20px;
  }
}
.send-quick-msg {
  display: inline-block;
  width: 96px;
  height: 32px;
  background: #F5F5F5;
  border: 1px solid #D9D9D9;
  color: #8C8C8C;
  font-size: 14px;
  font-weight: 400;
  line-height: 32px;
  cursor: pointer;
  .cate-icon {
    display: inline-block;
    width: 20px;
    height: 20px;
  }
}
.img-position {
  margin: -2px 6px 0;
  vertical-align: middle;
}
.margin-cate-send {
  margin-left: 12px;
}
.send-quick-msg-active {
  display: inline-block;
  width: 96px;
  height: 32px;
  background: #F5F5F5;
  border: 1px solid #3480FF;
  color: #3480FF;
  font-size: 14px;
  font-weight: 400;
  line-height: 32px;
  cursor: pointer;
  .cate-icon {
    display: inline-block;
    width: 20px;
    height: 20px;
  }
}
.quick-msg-wrap {
  height: 81px;
  overflow-y: auto;
  .quick-msg-item {
    margin-top: 16px;
    font-size: 16px
    font-weight: 400;
    color: #262626;
    line-height: 22px;
    cursor: pointer;
    white-space:nowrap;
    overflow:hidden;
    text-overflow:ellipsis;
  }
  .quick-msg-item:hover {
    color: red;
  }
}
</style>
